//
//  ThreadViewController.h
//  objective_c_language
//
//  Created by 王玉龙 on 2018/7/11.
//  Copyright © 2018年 longlong. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ThreadViewController : UIViewController

@end



/*
 // 问题1、：NSMachPort 是什么？为什么能保活分线程？
 问题2、：为何在线程通信中，主线程中到分线程的代码不被执行？
 问题3、：分线程中调用延迟执行方法，为何不被执行？
 
 */

/*API_AVAILABLE 有效的
 
 NSThread 简介：
 NSThread 偏向于底层，是对 pthread 的 OC 封装, 面向对象, 解决了 C 语言使用不方便的问题, 但是仍然需要程序员手动管理线程生命周期、处理线程同步等问题。是一个轻量级的多线程编程方法（相对GCD和NSOperation），
 
 
 NSThread 官方API：
 
 使用线程属性：
 
 
 
 
 
 
 
 1、属性
 2、线程创建：对于NSThread来说，每一个对象就代表着一个线程，NSThread提供了2种创建线程的方法:
 + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;
 - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument NS_AVAILABLE(10_5, 2_0);
 detach方法直接创建并启动一个线程去Selector，由于没有返回值，如果需要获取新创建的Thread，需要在执行的Selector中调用-[NSThread currentThread]获取
 init方法初始化线程并返回，线程的入口函数由Selector传入。线程创建出来之后需要手动调用 -start方法启动
 
 
 3、线程操作：创建好线程之后当然需要对线程进行操作，NSThread 给线程提供的主要操作方法有启动，睡眠，取消，退出
 启动：我们使用 init 方法将线程创建出来之后，线程并不会立即运行，只有我们手动调用-start方法才会启动线程
 这里要注意的是：部分线程属性需要在启动前设置，线程启动之后再设置会无效。如qualityOfService（优先级）属性
 睡眠：NSThread提供了2个让线程睡眠的方法，一个是根据NSDate传入睡眠时间，一个是直接传入NSTimeInterval
 + (void)sleepUntilDate:(NSDate *)date;
 + (void)sleepForTimeInterval:(NSTimeInterval)ti;
 
 题外话：runloop 的阻塞线程：
 sleepUntilDate:相当于执行一个sleep的任务。在执行过程中，即使有其他任务传入runloop，runloop也不会立即响应，必须sleep任务完成之后，才会响应其他任务
 runUntilDate:虽然会阻塞线程，阻塞过程中并不妨碍新任务的执行。当有新任务的时候，会先执行接收到的新任务，新任务执行完之后，如果时间到了，再继续执行runUntilDate:之后的代码
 
 取消：对于线程的取消，NSThread提供了一个取消的方法和一个属性
 
 退出：-exit函数可以让线程立即退出。
 -exit 调用之后会立即终止线程，即使任务还没有执行完成也会中断。这就非常有可能导致内存泄露等严重问题，所以一般不推荐使用。
 runloop启动的方法中run和runUntilDate:都无法使用CFRunLoopStop()退出，只有runMode:beforeDate:可以响应CFRunLoopStop()，所以要想使用CFRunLoopStop()退出runloop，必须使用runMode:beforeDate:启动
 
 线程通讯
 
 
 
 NSThread 使用：解决线程阻塞问题
 
 */


